#pragma once
#include <algorithm>
#include <chrono>
#include <iomanip>
#include <iostream>
#include <string>
#include <unordered_map>
namespace toolsLib
{

class Timer
{
  public:
    static Timer& getInstance();

    void begin(const std::string& file,
               const std::string& funcName,
               const int line,
               const std::string& startMessage);

    void begin(const std::string& file,
               const std::string& funcName,
               const int line,
               const int startMessage);

    void end(const std::string& file,
             const std::string& funcName,
             const int line,
             const int level,
             const std::string& endMessage);

    void end(const std::string& file,
             const std::string& funcName,
             const int line,
             const int level,
             const int endMessage);

    template <typename T>
    void templateBegin(const std::string& file,
                       const std::string& funcName,
                       const int line,
                       const T& startMessage);

    template <typename T>
    void templateEnd(const std::string& file,
                     const std::string& funcName,
                     const int line,
                     const int level,
                     const T& endMessage);

  private:
    Timer() {}
    Timer(const Timer&) = delete;
    Timer& operator=(const Timer&) = delete;

    std::string doubleToString(double num, int precision);
    static std::unordered_map<std::string,
                              std::chrono::time_point<std::chrono::high_resolution_clock>>
        startTimeString;
    static std::unordered_map<int, std::chrono::time_point<std::chrono::high_resolution_clock>>
        startTimeInt;

    static std::unordered_map<std::string, std::string> startFileString;
    static std::unordered_map<std::string, std::string> startFuncNameString;
    static std::unordered_map<std::string, int> startLineString;

    const long long microsecondsInSecond = 1000000LL;
};

}  // namespace toolsLib
